home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume18 / mush6.4 / part04 < prev    next >
Encoding:
Internet Message Format  |  1989-03-12  |  55.7 KB

  1. Subject:  v18i026:  Mail user's shell version 6.4, Part04/19
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Dan Heller <island!argv@sun.com>
  7. Posting-number: Volume 18, Issue 26
  8. Archive-name: mush6.4/part04
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 4 (of 19)."
  19. # Contents:  dates.c help.c macros.c main.c main_panel.c options.c
  20. # Wrapped by rsalz@papaya.bbn.com on Mon Mar 13 19:25:09 1989
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'dates.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'dates.c'\"
  24. else
  25. echo shar: Extracting \"'dates.c'\" \(8311 characters\)
  26. sed "s/^X//" >'dates.c' <<'END_OF_FILE'
  27. X/* @(#)dates.c    1.1    (c) copyright 10/15/86 (Dan Heller) */
  28. X
  29. X#include "mush.h"
  30. X
  31. X/*
  32. X *   %02d%02d%02d%02d%02d%s  yy mm dd hh mm weekday
  33. X * The standard "date format" stored in the msg data structure.
  34. X */
  35. Xchar *day_names[] = {
  36. X    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  37. X};
  38. Xchar *month_names[] = {     /* imported in pick.c */
  39. X    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  40. X    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  41. X};
  42. X
  43. X/* Time() returns a string according to criteria:
  44. X *   if "now" is 0, then the current time is gotten and used.
  45. X *       else, use the time described by now
  46. X *   opts points to a string of args which is parsed until an unknown
  47. X *       arg is found and opts will point to that upon return.
  48. X *   valid args are T (time of day), D (day of week), M (month), Y (year),
  49. X *       N (number of day in month -- couldn't think of a better letter).
  50. X */
  51. Xchar *
  52. XTime(opts, now)
  53. Xregister char *opts;
  54. Xlong now;
  55. X{
  56. X    static char time_buf[30];
  57. X    struct tm       *T;
  58. X    register char *p = time_buf;
  59. X    long      x;
  60. X
  61. X    if (!opts)
  62. X    return NULL;
  63. X    if (now)
  64. X    x = now;
  65. X    else
  66. X    (void) time(&x);
  67. X    T = localtime(&x);
  68. X    for (;; opts++) {
  69. X    switch(*opts) {
  70. X        case 'T':
  71. X        if (ison(glob_flags, MIL_TIME))
  72. X            (void) sprintf(p, "%2d:%02d", T->tm_hour, T->tm_min);
  73. X        else
  74. X            (void) sprintf(p, "%d:%02d", (T->tm_hour) ?
  75. X              ((T->tm_hour <= 12) ? T->tm_hour : T->tm_hour - 12) :
  76. X              12, T->tm_min);
  77. X        when 'D': case 'W': (void) strcpy(p, day_names[T->tm_wday]);
  78. X        when 'M': (void) strcpy(p, month_names[T->tm_mon]);
  79. X        when 'y': (void) sprintf(p, "%d", T->tm_year);
  80. X        when 'Y': (void) sprintf(p, "19%d", T->tm_year);
  81. X        when 'N': (void) sprintf(p, "%d", T->tm_mday);
  82. X        otherwise: *--p = 0; return time_buf;
  83. X    }
  84. X    p += strlen(p);
  85. X    *p++ = ' ';
  86. X    }
  87. X}
  88. X
  89. X/* parse date and return a string that looks like
  90. X *    "%2d%2d%2d%2d%2d%3c", wkday,yr,mo,date,hrs,mins
  91. X * This function is a bunch of scanfs on known date formats.  Don't
  92. X * trust the "weekday" name fields because they may not be spelled
  93. X * right, or have the correct punctuation.  Figure it out once the
  94. X * year and month and date have been determined.
  95. X */
  96. Xchar *
  97. Xparse_date(p)
  98. Xregister char *p;
  99. X{
  100. X    /* When scanf-ing if month isn't a month, it could be a _long_ string.
  101. X     * this is also the static buffer whose address we return.
  102. X     */
  103. X    static char month[64];
  104. X    char Wkday[4];
  105. X    int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1;
  106. X
  107. X    skipspaces(0);
  108. X
  109. X    /* Possible combinations that we could have:
  110. X     *   day_number month_name year_number time timezone ...
  111. X     *   day_name month_name day_number time year_number
  112. X     *   day_name month_name day_number year_number time
  113. X     *   day_name day_number month_name year_number time
  114. X     *   day_number month_name year_number time
  115. X     *   day_number month_name year_number time-timezone (day)
  116. X     *                                       ^no colon separator
  117. X     *   day_name month_name day_number time timezone year_number
  118. X     *   day_number-month_name-year time
  119. X     *   day_name, day_number-month_name-year time
  120. X     *   day_number month_name year_number, time "-"
  121. X     */
  122. X    /* programmer's note -- there are too many scanfs here for some compilers
  123. X     * to put them all into one if statement.  Use goto's :-(
  124. X     */
  125. X    if (sscanf(p, "%*s %s %d %d %d:%d", month,&Day,&Year,&Hours,&Mins) == 5)
  126. X    goto gotit;
  127. X    if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  128. X    goto gotit;
  129. X    if (sscanf(p, "%*s %s %d %d:%d:%*d %d", month,&Day,&Hours,&Mins,&Year) == 5)
  130. X    goto gotit;
  131. X    if (sscanf(p, "%*s %d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  132. X    goto gotit;
  133. X    if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  134. X    goto gotit;
  135. X    if (sscanf(p, "%d %s %d %2d%2d", &Day,month,&Year,&Hours,&Mins) == 5)
  136. X    goto gotit;
  137. X    if (sscanf(p, "%*s %s %d %d:%d:%*d %*s %d",
  138. X                    month, &Day, &Hours, &Mins, &Year) == 5)
  139. X    goto gotit;
  140. X    if (sscanf(p, "%*s %s %d %d:%d %*s %d",
  141. X                    month, &Day, &Hours, &Mins, &Year) == 5)
  142. X    goto gotit;
  143. X    if (sscanf(p,"%d-%[^-]-%d %d:%d", &Day, month, &Year, &Hours, &Mins) == 5)
  144. X    goto gotit;
  145. X    if (sscanf(p,"%d %s %d, %d:%d:%*d -",&Day, month, &Year, &Hours, &Mins)== 5)
  146. X    goto gotit;
  147. X    if (sscanf(p,"%*s %d-%[^-]-%d %d:%d",&Day, month, &Year, &Hours, &Mins)== 5)
  148. X    goto gotit;
  149. X    goto didnt_getit;
  150. Xgotit:
  151. X    if (Year > 99)
  152. X    Year %= 100;
  153. X    if ((Month = month_to_n(month)) == -1) {
  154. X    print("bad month: %s\n", p);
  155. X    return NULL;
  156. X    }
  157. X    {
  158. X    static int mtbl[]={0,31,59,90,120,151,181,212,243,273,304,334};
  159. X    int days_ctr;
  160. X
  161. X        days_ctr = ((Year * 365) + ((Year + 3) / 4) + mtbl[Month-1] + Day + 6);
  162. X        if (Month > 2 && (Year % 4 == 0))
  163. X        days_ctr++;
  164. X        (void) (sprintf(Wkday, "%.3s", day_names[days_ctr % 7]));
  165. X    }
  166. X    return sprintf(month, "%02d%02d%02d%02d%02d%s",
  167. X              Year, Month, Day, Hours, Mins, Wkday);
  168. Xdidnt_getit:
  169. X    if (ison(glob_flags, WARNING))
  170. X    print("Unknown date format: %s\n", p);
  171. X    return NULL;
  172. X}
  173. X
  174. X/* pass a string in the standard date format, put into string.
  175. X * return values in buffers provided they are not null.
  176. X */
  177. Xchar *
  178. Xdate_to_string(Date, Yr, Mon, Day, Wkday, Tm, ret_buf)
  179. Xchar *Date, *Yr, *Mon, *Day, *Wkday, *Tm, *ret_buf;
  180. X{
  181. X    unsigned int days_ctr;
  182. X    int yr, mon, day, hr, mins;
  183. X    char a_or_p, *p = ret_buf;
  184. X
  185. X    (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c",
  186. X    &yr, &mon, &day, &hr, &mins, Wkday);
  187. X    Wkday[3] = 0;
  188. X    a_or_p = (hr < 12)? 'a': 'p';
  189. X
  190. X    (void) sprintf(Yr, "19%d", yr);
  191. X    (void) sprintf(Day, "%d", day);
  192. X    (void) strcpy(Mon, month_names[mon-1]);
  193. X    p += strlen(sprintf(p, "%s %2.d, ", month_names[mon-1], day));
  194. X    if (ison(glob_flags, MIL_TIME))
  195. X    (void) sprintf(p, "%2d:%02d",hr,mins);
  196. X    else
  197. X    (void) sprintf(p, "%2.d:%02d%cm",
  198. X          (hr)? (hr <= 12)? hr: hr - 12: 12, mins, a_or_p);
  199. X    (void) strcpy(Tm, p);
  200. X    return ret_buf;
  201. X}
  202. X
  203. X/* pass a string in the internal mush date format.
  204. X * return pointer to static buffer holding ctime-format date.
  205. X */
  206. Xchar *
  207. Xdate_to_ctime(Date)
  208. Xchar *Date;
  209. X{
  210. X    static char ret_buf[32];
  211. X    char Wkday[4];
  212. X    int yr, mon, day, hr, mins;
  213. X
  214. X    (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c",
  215. X    &yr, &mon, &day, &hr, &mins, Wkday);
  216. X
  217. X    (void) sprintf(ret_buf, "%.3s %.3s %2.d %02d:%02d:00 19%d\n",
  218. X        Wkday, month_names[mon-1], day, hr, mins, yr);
  219. X
  220. X    return ret_buf;
  221. X}
  222. X
  223. X/*
  224. X * Build a date string according to the specification in the RFC for Date:
  225. X */
  226. Xchar *
  227. Xrfc_date(buf)
  228. Xchar buf[];
  229. X{
  230. X    struct tm       *T;
  231. X#ifdef SYSV
  232. X    long      x;
  233. X    extern char *tzname[];
  234. X    char *tz;
  235. X
  236. X    (void) time(&x);
  237. X    T = localtime(&x);
  238. X    tz = tzname[T->tm_isdst];
  239. X#else /* SYSV */
  240. X#ifdef BSD
  241. X    extern char     *timezone();
  242. X    struct timeval  mytime;
  243. X    struct timezone myzone;
  244. X    char *tz;
  245. X
  246. X    (void) gettimeofday(&mytime, &myzone);
  247. X    T = localtime(&mytime.tv_sec);
  248. X    tz = timezone(myzone.tz_minuteswest, (T->tm_isdst && myzone.tz_dsttime));
  249. X#else
  250. X    char *tz = "";
  251. X#endif /* BSD */
  252. X#endif /* !SYSV */
  253. X
  254. X    return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s",
  255. X    day_names[T->tm_wday],    /* day name */
  256. X    T->tm_mday,        /* day of the month */
  257. X    month_names[T->tm_mon],    /* month name */
  258. X    T->tm_year,        /* year number */
  259. X    T->tm_hour,        /* hours (24hr) */
  260. X    T->tm_min, T->tm_sec,    /* mins/secs */
  261. X    tz);            /* timezone */
  262. X}
  263. X
  264. X#define JAN    1
  265. X#define FEB    2
  266. X#define MAR    3
  267. X#define APR    4
  268. X#define MAY    5
  269. X#define JUN    6
  270. X#define JUL    7
  271. X#define AUG    8
  272. X#define SEP    9
  273. X#define OCT    10
  274. X#define NOV    11
  275. X#define DEC    12
  276. X
  277. X/* stolen direct from ELM */
  278. Xmonth_to_n(name)
  279. Xregister char *name;
  280. X{
  281. X    /** return the month number given the month name... **/
  282. X
  283. X    register char ch;
  284. X
  285. X    switch (lower(*name)) {
  286. X    case 'a' : if ((ch = lower(name[1])) == 'p')
  287. X               return(APR);
  288. X           else if (ch == 'u')
  289. X               return(AUG);
  290. X           else return(-1);    /* error! */
  291. X    case 'd' : return(DEC);
  292. X    case 'f' : return(FEB);
  293. X    case 'j' : if ((ch = lower(name[1])) == 'a')
  294. X               return(JAN);
  295. X           else if (ch == 'u') {
  296. X             if ((ch = lower(name[2])) == 'n')
  297. X             return(JUN);
  298. X             else if (ch == 'l')
  299. X             return(JUL);
  300. X             else return(-1);        /* error! */
  301. X           }
  302. X           else return(-1);        /* error */
  303. X    case 'm' : if ((ch = lower(name[2])) == 'r')
  304. X               return(MAR);
  305. X           else if (ch == 'y')
  306. X               return(MAY);
  307. X           else return(-1);        /* error! */
  308. X    case 'n' : return(NOV);
  309. X    case 'o' : return(OCT);
  310. X    case 's' : return(SEP);
  311. X    default  : return(-1);
  312. X    }
  313. X}
  314. END_OF_FILE
  315. if test 8311 -ne `wc -c <'dates.c'`; then
  316.     echo shar: \"'dates.c'\" unpacked with wrong size!
  317. fi
  318. # end of 'dates.c'
  319. fi
  320. if test -f 'help.c' -a "${1}" != "-c" ; then 
  321.   echo shar: Will not clobber existing file \"'help.c'\"
  322. else
  323. echo shar: Extracting \"'help.c'\" \(9302 characters\)
  324. sed "s/^X//" >'help.c' <<'END_OF_FILE'
  325. X/* @(#)help.c    (c) copyright 10/15/86 (Dan Heller) */
  326. X
  327. X/*
  328. X * This file contains two main routines:
  329. X *    display_help() and find_help()
  330. X * Both are virtually equivalent in functionality; they are passed
  331. X * a char * or a char **. If a char * is passed, then open "file"
  332. X * argument (containing help strings) and search for %str% and read
  333. X * the following text until %% or EOF into a local buffer.
  334. X * If str is a char **, then that array of strings is used directly.
  335. X *
  336. X * If display_help is used, then the final array of strings used is
  337. X * displayed in the center of the bitmapped console in a box with
  338. X * shading and the user must hit the left mouse button to remove the
  339. X * message.  the fd passed is the fd of the window locking the screen.
  340. X *
  341. X * In text mode, the routine find_help is used (or, if the graphics
  342. X * mode doesn't want to lock the screen to display a message). The
  343. X * same actions occur, but instead of "ifdef"ing up one function, I
  344. X * just made two for readability.
  345. X */
  346. X#include <stdio.h>
  347. X#include "strings.h"
  348. X
  349. X#define NULL_FILE (FILE *)0
  350. X
  351. X#ifdef SUNTOOL
  352. X#include <suntool/tool_hs.h>
  353. X#include <signal.h>
  354. X#include <suntool/fullscreen.h>
  355. X
  356. X#define l_width()      font->pf_defaultsize.x /* width of letter */
  357. X#define l_height()      font->pf_defaultsize.y /* height of letter */
  358. X
  359. X#define draw(win,x1,y1,x2,y2,OP)     pw_vector(win, x1,y1,x2,y2,OP,1)
  360. X#define box(win, x1,y1,x2,y2,OP) \
  361. X    draw(win,x1,y1, x1,y2, OP), \
  362. X    draw(win,x1,y2, x2,y2, OP), \
  363. X    draw(win,x2,y2, x2,y1, OP), \
  364. X    draw(win,x2,y1, x1,y1, OP)
  365. X
  366. X#define DEF_CONT_MSG    "Click LEFT mouse Button to continue."
  367. XDEFINE_CURSOR(oldcursor, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  368. X
  369. X/* shading */
  370. Xstatic short dat_shade_25[] = {
  371. X#include <images/square_25.pr>
  372. X};
  373. X
  374. Xstatic short dat_shade_50[] = {
  375. X#include <images/square_50.pr>
  376. X};
  377. X
  378. Xstatic short dat_shade_75[] = {
  379. X#include <images/square_75.pr>
  380. X};
  381. X
  382. Xstatic short dat_mouse_left[] = {
  383. X#include <images/confirm_left.pr> 
  384. X};
  385. X
  386. Xmpr_static(shade_25,        16, 16, 1, dat_shade_25);
  387. Xmpr_static(shade_50,        16, 16, 1, dat_shade_50);
  388. Xmpr_static(shade_75,        16, 16, 1, dat_shade_75);
  389. Xmpr_static(confirm_pr,      16, 16, 1, dat_mouse_left);
  390. X
  391. Xstatic struct cursor confirm_cursor = { 3, 3, PIX_SRC, &confirm_pr };
  392. Xstatic struct pixrect *shading;
  393. X
  394. X#else
  395. X
  396. X#include <sys/types.h>
  397. X#define wprint printf
  398. X#define print  printf
  399. X#define TRUE   1
  400. X#define FALSE  0
  401. X
  402. X#endif /* SUNTOOL */
  403. X
  404. X/* what to print if nothing was found */
  405. Xstatic char *def_msg[] = {
  406. X    "There is no help found for \"%s\".",
  407. X    "Perhaps getting help from another item",
  408. X    "would be of some use.", 0
  409. X};
  410. X
  411. X#define MAXLINES    40
  412. X#define MAXLENGTH    128
  413. X
  414. X#ifdef SUNTOOL
  415. Xdisplay_help(fd, str, file, font)
  416. Xregister caddr_t *str;   /* could be a single or double pointer */
  417. Xregister char *file;
  418. Xregister struct pixfont *font;
  419. X{
  420. X    struct fullscreen *fs;
  421. X    struct inputmask im, old_im;
  422. X    struct inputevent event;
  423. X    struct rect rect;
  424. X    register char *p;
  425. X    register int x, y, z, height;
  426. X    struct pixrect *saved, *save_bits();
  427. X    int width = 0, old_link;
  428. X    char *cont_msg = DEF_CONT_MSG, *getenv();
  429. X    char args[MAXLINES][MAXLENGTH], help_str[40];
  430. X    FILE *fp;
  431. X
  432. X    if (!shading)
  433. X    if (p = getenv("SHADE")) {
  434. X        register int x = atoi(p);
  435. X        if (x <= 25)
  436. X        shading = &shade_25;
  437. X        else if (x <= 50)
  438. X        shading = &shade_50;
  439. X        else
  440. X        shading = &shade_75;
  441. X    } else
  442. X        shading = &shade_25;
  443. X
  444. X    /* If no file given, take "str" arg as message to print */
  445. X    if (!file || !*file) {
  446. X    for (height = 0; *str && height < MAXLINES-1; height++) {
  447. X        if (!compose_str(*str, &width))
  448. X        break;
  449. X        (void) strcpy(args[height], *str++);
  450. X    }
  451. X    } else {
  452. X    if (!(fp = fopen(file, "r")))
  453. X        return -1;
  454. X    /* look for %str% in helpfile */
  455. X    (void) sprintf(help_str, "%%%s%%\n", str);
  456. X
  457. X    while(p = fgets(args[0], MAXLENGTH, fp))
  458. X        if (*p == '%' && !strcmp(p, help_str))
  459. X        break;
  460. X
  461. X    if (!p || !fgets(args[0], MAXLENGTH, fp)) {
  462. X        char buf[64];
  463. X        for(height = 0; def_msg[height] && height < MAXLINES-1; height++) {
  464. X        sprintf(buf, def_msg[height], str);
  465. X        compose_str(buf, &width);
  466. X        (void) strcpy(args[height], buf);
  467. X        }
  468. X    } else
  469. X        for (height = 0; p && *p && strcmp(p, "%%\n"); height++) {
  470. X        compose_str(p, &width);
  471. X        p = fgets(args[height+1], MAXLENGTH, fp);
  472. X        }
  473. X    }
  474. X    if (height == MAXLINES - 1)
  475. X    print("Help message is too long!\n");
  476. X
  477. X    fclose(fp);
  478. X
  479. X    fs = fullscreen_init(fd);
  480. X    /* Figure out the height and width in pixels (rect.r_height, rect.r_width)
  481. X     * Remember to provide for the "confirm" line (cont_msg).
  482. X     * extend the new box by 15 pixels on the sides (30 total), top, and bottom.
  483. X     * finally, add 16 pixels for "shadow" -- remove before clearing area
  484. X     * to preserve background and give a shadow-like appearance.
  485. X     */
  486. X    if ((x = strlen(cont_msg)) > width)
  487. X    width = x; /* this x value must be saved! */
  488. X    rect.r_width = (width*l_width()) + 30 + 16;
  489. X    rect.r_height = ((height+1) * l_height()) + 30 + 16;
  490. X    rect.r_left = fs->fs_screenrect.r_left +
  491. X    (fs->fs_screenrect.r_width / 2) - (rect.r_width / 2);
  492. X    rect.r_top = fs->fs_screenrect.r_top +
  493. X    (fs->fs_screenrect.r_height / 2) - (rect.r_height / 2);
  494. X
  495. X    /* save old area */
  496. X    saved = save_bits(fs->fs_pixwin, &rect);
  497. X
  498. X    /* prepare surface, clear the background, and reset rect for shadow */
  499. X    pw_preparesurface(fs->fs_pixwin, &rect);
  500. X    pw_lock(fs->fs_pixwin, &rect);
  501. X    rect.r_width -= 16;
  502. X    rect.r_height -= 16;
  503. X
  504. X    pw_writebackground(fs->fs_pixwin,
  505. X    rect.r_left, rect.r_top, rect.r_width, rect.r_height, PIX_CLR);
  506. X
  507. X    /* make a box that's 5 pixels thick. Then add a thin box inside it */
  508. X    for (z = 0; z < 5; z++)
  509. X    box(fs->fs_pixwin,
  510. X        rect.r_left+z, rect.r_top+z,
  511. X        rect.r_left+rect.r_width-z-1, rect.r_top+rect.r_height-z-1,
  512. X        PIX_SRC);
  513. X    box(fs->fs_pixwin,
  514. X    rect.r_left+z+2, rect.r_top+z+2,
  515. X    rect.r_left+rect.r_width-z-3, rect.r_top+rect.r_height-z-3,
  516. X    PIX_SRC);
  517. X
  518. X    /* shading -- pw_replrop() doesn't work (bug)
  519. X     * NOTE: fs->fs_screenrect.r_top and r_left are negative values
  520. X     */
  521. X    pr_replrop(fs->fs_pixwin->pw_pixrect,
  522. X       rect.r_left + rect.r_width - fs->fs_screenrect.r_left,
  523. X       rect.r_top + 16 - fs->fs_screenrect.r_top,
  524. X       16, rect.r_height-16, PIX_SRC|PIX_DST, shading, 0, 0);
  525. X    pr_replrop(fs->fs_pixwin->pw_pixrect,
  526. X       rect.r_left + 16 - fs->fs_screenrect.r_left,
  527. X       rect.r_top+rect.r_height - fs->fs_screenrect.r_top,
  528. X       rect.r_width, 16, PIX_SRC|PIX_DST, shading, 0, 0);
  529. X
  530. X    if (x > width)
  531. X    x = 15;
  532. X    else
  533. X    x = rect.r_width/2 - (x*l_width())/2;
  534. X    y = rect.r_height - 15;
  535. X
  536. X    /* Print everything in reverse order now; start with the "confirm" string
  537. X     * (which is centered and highlighted)
  538. X     */
  539. X    pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y, PIX_SRC,font, cont_msg);
  540. X    pw_text(fs->fs_pixwin, rect.r_left+x+1, rect.r_top+y, PIX_SRC|PIX_DST, font,
  541. X        cont_msg);
  542. X
  543. X    y -= (5 + l_height());
  544. X    x = 15;
  545. X
  546. X    /* now print each string in reverse order (start at bottom of box) */
  547. X    for (height--; height >= 0; height--) {
  548. X    pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y,
  549. X        PIX_SRC, font, args[height]);
  550. X    y -= l_height();
  551. X    }
  552. X
  553. X    pw_unlock(fs->fs_pixwin);
  554. X
  555. X    /* wait for user to read and confirm */
  556. X    win_getinputmask(fd, &old_im, &old_link);
  557. X    input_imnull(&im);
  558. X    im.im_flags |= IM_ASCII;
  559. X    win_setinputcodebit(&im, MS_LEFT);
  560. X    win_setinputcodebit(&im, MS_MIDDLE);
  561. X    win_setinputcodebit(&im, MS_RIGHT);
  562. X    win_setinputmask(fd, &im, &im, WIN_NULLLINK);
  563. X    win_getcursor(fd, &oldcursor);
  564. X    win_setcursor(fd, &confirm_cursor);
  565. X    while (input_readevent(fd, &event) != -1 && event.ie_code != MS_LEFT);
  566. X
  567. X    /* restore old cursor */
  568. X    win_setcursor(fd, &oldcursor);
  569. X
  570. X    /* restore old pixrect (size already restored) */
  571. X    rect.r_height += 16; /* to take care of the shadow */
  572. X    rect.r_width += 16;
  573. X    restore_bits(fs->fs_pixwin, &rect, saved);
  574. X    /* release screen */
  575. X    fullscreen_destroy(fs);
  576. X    win_setinputmask(fd, &old_im, &old_im, old_link);
  577. X    return 0;
  578. X}
  579. X
  580. Xstatic
  581. Xcompose_str(p, width)
  582. Xregister char *p;
  583. Xint *width;
  584. X{
  585. X    register int x;
  586. X    if (!p || !*p)
  587. X    return 0;
  588. X    x = strlen(p);
  589. X    if (p[x-1] == '\n')
  590. X    p[--x] = 0; /* get rid of newline */
  591. X    if (x > *width)
  592. X    *width = x;
  593. X    return 1;
  594. X}
  595. X#endif /* SUNTOOL */
  596. X
  597. Xfind_help(str, file)
  598. Xregister caddr_t *str;
  599. Xregister char *file;
  600. X{
  601. X    register char    *p;
  602. X    char        buf[BUFSIZ], help_str[40];
  603. X    register int    height;
  604. X    extern char        *no_newln();
  605. X    FILE        *fp;
  606. X
  607. X    /* If no file given, take "str" arg as message to print */
  608. X    if (!file || !*file) {
  609. X    /* use the pager on the args to the function */
  610. X    do_pager(NULL, TRUE);
  611. X    while (*str) {
  612. X        (void) do_pager(*str++, FALSE);
  613. X        if (do_pager("\n", FALSE) == EOF)
  614. X        break;
  615. X    }
  616. X    do_pager(NULL, FALSE);
  617. X    return 0;
  618. X    }
  619. X
  620. X    if (!(fp = fopen(file, "r")))
  621. X    return -1;
  622. X    /* look for %str% in helpfile */
  623. X    (void) sprintf(help_str, "%%%s%%\n", str);
  624. X
  625. X    while (p = fgets(buf, sizeof buf, fp))
  626. X    if (*p == '%' && !strcmp(p, help_str))
  627. X        break;
  628. X    if (!p)
  629. X    /* Didn't find the help requested */
  630. X    for (height = 0; def_msg[height]; height++) {
  631. X        wprint(def_msg[height], str);
  632. X        wprint("\n");
  633. X    }
  634. X    else {
  635. X    do_pager(NULL, TRUE);
  636. X    while ((p = fgets(buf, sizeof buf, fp)) && strcmp(p, "%%\n"))
  637. X        if (do_pager(buf, FALSE) == EOF)
  638. X        break;
  639. X    do_pager(NULL, FALSE);
  640. X    }
  641. X    fclose(fp);
  642. X
  643. X    return 0;
  644. X}
  645. END_OF_FILE
  646. if test 9302 -ne `wc -c <'help.c'`; then
  647.     echo shar: \"'help.c'\" unpacked with wrong size!
  648. fi
  649. # end of 'help.c'
  650. fi
  651. if test -f 'macros.c' -a "${1}" != "-c" ; then 
  652.   echo shar: Will not clobber existing file \"'macros.c'\"
  653. else
  654. echo shar: Extracting \"'macros.c'\" \(8623 characters\)
  655. sed "s/^X//" >'macros.c' <<'END_OF_FILE'
  656. X/* (@)# macros.c    (c) copyright 9/19/88 (Bart Schaefer, Dan Heller) */
  657. X
  658. X#include "bindings.h"
  659. X#include "mush.h"
  660. X
  661. Xextern struct cmd_map map_func_names[];
  662. X
  663. Xstruct cmd_map    *mac_stack, *mac_hide;
  664. X
  665. Xextern char *calloc();
  666. X
  667. X/*
  668. X * print current binding to macro mappings if "str" is NULL.
  669. X * else return the string "x_str" which the str is bound to.
  670. X */
  671. Xchar *
  672. Xc_macro(name, str, opts)
  673. Xchar *name;
  674. Xregister char *str;
  675. Xregister struct cmd_map *opts;
  676. X{
  677. X    register int    incurses = iscurses;
  678. X    char buf[MAX_MACRO_LEN], buf2[sizeof buf * 3];
  679. X
  680. X    if (!str) {
  681. X    for (; opts; opts = opts->m_next)
  682. X        if (opts->m_cmd == C_MACRO)
  683. X        break;
  684. X    if (!opts) {
  685. X        print("No %s settings.\n", name);
  686. X        return (char *)(-1);
  687. X    }
  688. X    if (incurses)
  689. X        clr_bot_line(), iscurses = FALSE;
  690. X    (void) do_pager(NULL, TRUE);
  691. X    (void) do_pager(sprintf(buf, "\nCurrent %s settings:\n\n",name), FALSE);
  692. X    }
  693. X
  694. X    if (!opts)
  695. X    return NULL;
  696. X
  697. X    for (; opts; opts = opts->m_next) {
  698. X    if (opts->m_cmd != C_MACRO)
  699. X        continue;
  700. X    if (!str) {
  701. X        (void) do_pager(sprintf(buf, "%-20.20s  ",
  702. X        ctrl_strcpy(buf2, opts->m_str, FALSE)), FALSE);
  703. X        if (do_pager(sprintf(buf, "%s\n",
  704. X        ctrl_strcpy(buf2, opts->x_str, TRUE)), FALSE) == EOF)
  705. X        break;
  706. X    } else {
  707. X        if (strcmp(str, opts->m_str))
  708. X        continue;
  709. X        else
  710. X        return opts->x_str;
  711. X    }
  712. X    }
  713. X    iscurses = incurses;
  714. X    if (str)
  715. X    (void) do_pager(NULL, FALSE);
  716. X    return NULL;
  717. X}
  718. X
  719. Xmac_push(str)
  720. Xregister char *str;
  721. X{
  722. X    register struct cmd_map *tmp;
  723. X
  724. X    /* now make a new macro struct and set fields */
  725. X    if (!(tmp = (struct cmd_map *)calloc((unsigned)1,sizeof(struct cmd_map)))) {
  726. X    error("calloc");
  727. X    return -1;
  728. X    }
  729. X    tmp->m_next = mac_stack;
  730. X    mac_stack = tmp;
  731. X    tmp->x_str = savestr(str);    /* x_str is the text of the expansion */
  732. X    tmp->m_str = tmp->x_str;    /* m_str is the current read position */
  733. X
  734. X    /*
  735. X     * Save the current state of the glob_flags so
  736. X     * mac_push() can also serve as unget of stdin
  737. X     */
  738. X    tmp->m_cmd = glob_flags;
  739. X    return 0;
  740. X}
  741. X
  742. Xvoid
  743. Xmac_pop()
  744. X{
  745. X    register struct cmd_map *tmp;
  746. X
  747. X    if (mac_stack) {
  748. X    tmp = mac_stack;
  749. X    mac_stack = tmp->m_next;
  750. X    xfree(tmp->x_str);
  751. X    xfree(tmp);
  752. X    }
  753. X    /*
  754. X     * Restore saved MACRO glob_flags only (see mac_push())
  755. X     */
  756. X    if (mac_stack) {
  757. X    if (ison(mac_stack->m_cmd, IN_MACRO))
  758. X        turnon(glob_flags, IN_MACRO);
  759. X    else
  760. X        turnoff(glob_flags, IN_MACRO);
  761. X    if (ison(mac_stack->m_cmd, LINE_MACRO))
  762. X        turnon(glob_flags, LINE_MACRO);
  763. X    else
  764. X        turnoff(glob_flags, LINE_MACRO);
  765. X    if (ison(mac_stack->m_cmd, QUOTE_MACRO))
  766. X        turnon(glob_flags, QUOTE_MACRO);
  767. X    else
  768. X        turnoff(glob_flags, QUOTE_MACRO);
  769. X    }
  770. X}
  771. X
  772. X/* Abandon macro processing */
  773. Xvoid
  774. Xmac_flush()
  775. X{
  776. X    while (mac_stack)
  777. X    mac_pop();
  778. X    if (mac_hide) {
  779. X    mac_stack = mac_hide;
  780. X    mac_hide = NULL_MAP;
  781. X    while (mac_stack)
  782. X        mac_pop();
  783. X    }
  784. X    turnoff(glob_flags, IN_MACRO);
  785. X    turnoff(glob_flags, LINE_MACRO);
  786. X    turnoff(glob_flags, QUOTE_MACRO);
  787. X}
  788. X
  789. X/* Check for pending input from a macro. */
  790. Xmac_pending()
  791. X{
  792. X    register struct cmd_map *msp;
  793. X
  794. X    for (msp = mac_stack; msp && !*(msp->m_str); msp = msp->m_next)
  795. X    ;
  796. X
  797. X    return !!msp;
  798. X}
  799. X
  800. X/* Get input and treat it as a macro.  */
  801. Xget_mac_input(newline)
  802. Xint newline;    /* 1 if newline to be appended, 0 otherwise */
  803. X{
  804. X    register int len;
  805. X    char buf[MAX_MACRO_LEN];
  806. X
  807. X    /* This call cannot be nested */
  808. X    if (mac_hide)
  809. X    return -1;
  810. X
  811. X    /* Hide the mac_stack so input comes from stdin */
  812. X    mac_hide = mac_stack; mac_stack = NULL_MAP;
  813. X
  814. X    if ((len = Getstr(buf, MAX_MACRO_LEN - 1, 0)) < 0)
  815. X    return len;
  816. X    if (newline) {
  817. X    buf[len++] = '\n';
  818. X    buf[len] = 0;
  819. X    }
  820. X
  821. X    /* Restore the mac_stack */
  822. X    if (mac_stack) {
  823. X    /*
  824. X     * Somehow, a push happened even though mac_hide was
  825. X     * nonzero -- maybe by line wrap?  Fix it as best we can.
  826. X     */
  827. X    struct cmd_map *msp;
  828. X    for (msp = mac_stack; msp->m_next; msp = msp->m_next)
  829. X        ;
  830. X    msp->m_next = mac_hide;
  831. X    } else
  832. X    mac_stack = mac_hide;
  833. X    mac_hide = NULL_MAP;
  834. X
  835. X    /* Restore saved flags */
  836. X    if (mac_stack) {
  837. X    if (ison(mac_stack->m_cmd, IN_MACRO))
  838. X        turnon(glob_flags, IN_MACRO);
  839. X    else
  840. X        turnoff(glob_flags, IN_MACRO);
  841. X    if (ison(mac_stack->m_cmd, LINE_MACRO))
  842. X        turnon(glob_flags, LINE_MACRO);
  843. X    else
  844. X        turnoff(glob_flags, LINE_MACRO);
  845. X    }
  846. X    if (len > 0)
  847. X    Ungetstr(buf);
  848. X
  849. X    return 1;
  850. X}
  851. X
  852. X/* getchar() substitute -- reads from the current macro if one is active,
  853. X * otherwise does a getchar().
  854. X *
  855. X * NOTE:  In the mac_stack, x_str is the saved text of the current macro,
  856. X *  and m_str is the current read position within the macro.
  857. X */
  858. Xm_getchar()
  859. X{
  860. X    register char c;
  861. X
  862. X    while (mac_stack && (! *(mac_stack->m_str)))
  863. X    mac_pop();
  864. X    if (mac_stack) {
  865. X    c = *((mac_stack->m_str)++);
  866. X    return c;
  867. X    } else {
  868. X    turnoff(glob_flags, IN_MACRO);
  869. X    turnoff(glob_flags, LINE_MACRO);
  870. X    turnoff(glob_flags, QUOTE_MACRO);
  871. X    while ((c = getchar()) == 0)    /* Ignore NUL chars from stdin */
  872. X        ;                /* until better solution found */
  873. X    return c;
  874. X    }
  875. X}
  876. X
  877. Xm_ungetc(c)
  878. Xregister char c;
  879. X{
  880. X    if (mac_stack && (mac_stack->m_str > mac_stack->x_str))
  881. X    *(--(mac_stack->m_str)) = c;
  882. X    else
  883. X    (void) ungetc(c, stdin);
  884. X}
  885. X
  886. X/*
  887. X * Try to read a long command; assumes MAC_LONG_CMD already seen.
  888. X *  On immediate failure, return 0.
  889. X *  On failure after reading some input, return less than zero.
  890. X *  On success, return greater than 0.
  891. X * The absolute value of the return is the number of chars placed in buf.
  892. X */
  893. Xread_long_cmd (buf)
  894. Xchar *buf;
  895. X{
  896. X    register char c, *p = buf;
  897. X    register int count = 0;
  898. X
  899. X    /*
  900. X     * Test in_macro() in this loop because the _entire_
  901. X     * long command _must_ be in the macro -- if we run
  902. X     * out of macro in mid-long-command, it is an error.
  903. X     */
  904. X    while (in_macro() && (count < MAX_LONG_CMD - 1)
  905. X        && ((c = m_getchar()) != MAC_LONG_END)) {
  906. X    *p++ = c; ++count;
  907. X    }
  908. X    *p = '\0';
  909. X    if (c != MAC_LONG_END)
  910. X    return (-count);
  911. X    return count;
  912. X}
  913. X
  914. X/*
  915. X * Identify and possibly execute a reserved long macro command
  916. X * Executes if do_exec is true.  Otherwise, just parse.
  917. X */
  918. Xreserved_cmd (buf, do_exec)
  919. Xchar *buf;
  920. X{
  921. X    int ret = 1;
  922. X
  923. X    if (!strcmp(buf, MAC_GET_STR)) {
  924. X        if (do_exec)
  925. X            ret = get_mac_input(0);
  926. X    } else if (!strcmp(buf, MAC_GET_LINE)) {
  927. X        if (do_exec)
  928. X            ret = get_mac_input(1);
  929. X    } else
  930. X        ret = 0;
  931. X    return ret;
  932. X}
  933. X
  934. X#ifdef CURSES
  935. X
  936. X/*
  937. X * Identify (and possibly execute, if reserved) curses mode commands
  938. X *  that appear in macro strings enclosed by MAC_LONG_CMD and
  939. X *  MAC_LONG_END.  Return the binding of the command.
  940. X */
  941. Xlong_mac_cmd (c, do_exec)
  942. Xint c;
  943. X{
  944. X    char buf[MAX_LONG_CMD];
  945. X    register int count, binding;
  946. X    int y, x;
  947. X
  948. X    if (c != MAC_LONG_CMD)
  949. X    return C_ERROR;
  950. X
  951. X    if ((count = read_long_cmd(buf)) <= 0) {
  952. X    print("Invalid long macro command");
  953. X    if (ison(glob_flags, CNTD_CMD))
  954. X        putchar('\n');
  955. X    if (do_exec)
  956. X        mac_flush();
  957. X    return C_ERROR;
  958. X    }
  959. X
  960. X    if (do_exec) {
  961. X    if (ison(glob_flags, CNTD_CMD))
  962. X        clr_bot_line();
  963. X    getyx(stdscr, y, x);
  964. X    move(LINES - 1, 0);
  965. X    }
  966. X    if (reserved_cmd(buf, do_exec)) {
  967. X    if (do_exec) {
  968. X        if (isoff(glob_flags, CNTD_CMD))
  969. X        move(y, x);
  970. X        return getcmd();
  971. X    } else
  972. X        return C_NULL;
  973. X    } else if (do_exec)
  974. X    move(y, x);
  975. X
  976. X    /* Can start at C_NULL because of "no-op" command */
  977. X    for (count = 0; count <= C_HELP; count++) {
  978. X    if (!strcmp(buf, map_func_names[count].m_str)) {
  979. X        binding = (int)map_func_names[count].m_cmd;
  980. X        break;
  981. X    }
  982. X    }
  983. X    /* Don't allow C_MACRO to be called directly */
  984. X    if (count > C_HELP || binding == C_MACRO) {
  985. X    print("Invalid long macro command");
  986. X    if (ison(glob_flags, CNTD_CMD))
  987. X        putchar('\n');
  988. X    return C_ERROR;
  989. X    } else
  990. X    return binding;
  991. X}
  992. X
  993. X#endif /* CURSES */
  994. X
  995. X/*
  996. X * Check the validity of a macro binding as far as possible
  997. X */
  998. Xcheck_mac_bindings(buf)
  999. Xchar *buf;
  1000. X{
  1001. X    int ok = TRUE;
  1002. X
  1003. X    while (ok && buf && *buf) {
  1004. X    if (*buf == MAC_LONG_CMD) {
  1005. X        char *i;
  1006. X#ifdef CURSES
  1007. X        int count;
  1008. X#endif /* CURSES */
  1009. X
  1010. X        if (ok)
  1011. X        ok = ((i = index(++buf, MAC_LONG_END)) != NULL);
  1012. X        if (i)
  1013. X            *i = '\0';      /* Don't worry, we'll fix it */
  1014. X        else
  1015. X            return ok;
  1016. X#ifdef CURSES
  1017. X        /* OK to start at C_NULL because of "no-op" command */
  1018. X        for (count = 0; count <= C_HELP; count++)
  1019. X            if (! strcmp(buf, map_func_names[count].m_str))
  1020. X                break;
  1021. X        /* Don't allow C_MACRO to be called directly */
  1022. X        if (count == C_MACRO)
  1023. X            ok = FALSE;
  1024. X        else if (count > C_HELP)
  1025. X#endif /* CURSES */
  1026. X        if (ok && !(ok = reserved_cmd(buf, FALSE)))
  1027. X        wprint("Warning: unrecognized curses command: \"%s\"\n", buf);
  1028. X        buf = i;
  1029. X        *buf++ = MAC_LONG_END;
  1030. X    } else if (*buf++ == '\\' && *buf)
  1031. X        ++buf;
  1032. X    }
  1033. X    return ok;
  1034. X}
  1035. END_OF_FILE
  1036. if test 8623 -ne `wc -c <'macros.c'`; then
  1037.     echo shar: \"'macros.c'\" unpacked with wrong size!
  1038. fi
  1039. # end of 'macros.c'
  1040. fi
  1041. if test -f 'main.c' -a "${1}" != "-c" ; then 
  1042.   echo shar: Will not clobber existing file \"'main.c'\"
  1043. else
  1044. echo shar: Extracting \"'main.c'\" \(8512 characters\)
  1045. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  1046. X/* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  1047. X
  1048. X#include "mush.h"
  1049. X#include "options.h"
  1050. X
  1051. X#define PATCHDATE "3/12/89" /* Here because EVERYTHING depends on mush.h */
  1052. X
  1053. X#if defined(sun) && defined(M_DEBUG)
  1054. Xcpu()
  1055. X{
  1056. X    print("CPU time limit exceeded!\n");
  1057. X}
  1058. X#endif /* sun && DEBUG */
  1059. X
  1060. X#ifdef LCKDFLDIR
  1061. Xextern char *lckdfldir;
  1062. X#endif /* LCKDFLDIR */
  1063. X
  1064. X#ifdef DOT_LOCK
  1065. Xint sgid;
  1066. X#ifdef BSD
  1067. Xint rgid;
  1068. X#endif /* BSD */
  1069. X#endif /* DOT_LOCK */
  1070. X
  1071. X/*ARGSUSED*/   /* we ignore envp */
  1072. Xmain(argc, argv)
  1073. Xchar **argv;
  1074. X{
  1075. X    int              n;
  1076. X    char           buf[256];
  1077. X    register char    *p;
  1078. X    char        **args;
  1079. X    struct mush_flags Flags;
  1080. X
  1081. X#ifdef LCKDFLDIR
  1082. X    lckdfldir = LCKDFLDIR;
  1083. X#endif /* LCKDFLDIR */
  1084. X    if (prog_name = rindex(*argv, '/'))
  1085. X    prog_name++;
  1086. X    else
  1087. X    prog_name = *argv;
  1088. X
  1089. X    (void) signal(SIGBUS,  bus_n_seg);
  1090. X    (void) signal(SIGSEGV, bus_n_seg);
  1091. X    (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
  1092. X
  1093. X#if defined(sun) && defined(M_DEBUG)
  1094. X    (void) signal(SIGXCPU, cpu);
  1095. X
  1096. X    if (p = getenv("MALLOC_DEBUG"))
  1097. X    malloc_debug(atoi(p));
  1098. X    else
  1099. X    malloc_debug(0);
  1100. X#endif /* sun && debug */
  1101. X
  1102. X    if (!isatty(0))
  1103. X    turnon(glob_flags, REDIRECT);
  1104. X
  1105. X    n = 0; /* don't ignore no such file or directory */
  1106. X    p = getpath(COMMAND_HELP, &n);
  1107. X
  1108. X    if (n)
  1109. X    cmd_help = "cmd_help";
  1110. X    else
  1111. X    strdup(cmd_help, p);
  1112. X
  1113. X    init(); /* must be done before checking mail since "login" is set here */
  1114. X#ifdef HOMEMAIL
  1115. X    {
  1116. X    char *home = do_set(set_options, "home");
  1117. X    if (!home)
  1118. X        home = "";
  1119. X    strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE));
  1120. X    }
  1121. X#else /* HOMEMAIL */
  1122. X    strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  1123. X#endif /* HOMEMAIL */
  1124. X
  1125. X    args = DUBL_NULL;
  1126. X    n = preparse_opts(&argc,argv,&args);
  1127. X
  1128. X    /* check for any mail at all and exit if we're not continuing */
  1129. X    if (!n) {
  1130. X    struct stat statb;
  1131. X    if (stat(spoolfile, &statb) || statb.st_size == 0) {
  1132. X        printf("No mail for %s.\n", login);
  1133. X        exit(0);
  1134. X    }
  1135. X    }
  1136. X
  1137. X#ifdef DOT_LOCK
  1138. X    sgid = getegid();
  1139. X#ifdef BSD
  1140. X    rgid = getgid();
  1141. X    setregid(sgid, rgid);
  1142. X#else
  1143. X    setgid(getgid());
  1144. X#endif /* BSD */
  1145. X#endif /* DOT_LOCK */
  1146. X
  1147. X    parse_options(&argv, &Flags);
  1148. X
  1149. X    if (Flags.source_rc) {
  1150. X    /* use cmd_line() in case DEFAULT_RC has expandable chars */
  1151. X    (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  1152. X    (void) source(0, DUBL_NULL);
  1153. X    }
  1154. X    if (*spoolfile != '/') {
  1155. X    n = 1;
  1156. X    p = getpath(spoolfile, &n);
  1157. X    if (n == -1)
  1158. X        fputs(p, stderr), exit(1);
  1159. X    else if (n)
  1160. X        fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1);
  1161. X    else
  1162. X        strdup(spoolfile, p);
  1163. X    }
  1164. X
  1165. X    set_cwd();  /* call _after_ sourcing files */
  1166. X
  1167. X#ifdef SUNTOOL
  1168. X    if (istool)
  1169. X    if (ison(glob_flags, REDIRECT))
  1170. X        puts("You can't redirect input to a tool."), exit(1);
  1171. X    else
  1172. X        make_tool(args), turnon(glob_flags, DO_SHELL);
  1173. X#endif /* SUNTOOL */
  1174. X
  1175. X    /* now we're ready for I/O */
  1176. X    if (isoff(glob_flags, REDIRECT)) {
  1177. X    /* make sure we can always recover from no echo mode */
  1178. X    (void) signal(SIGINT, catch);
  1179. X    (void) signal(SIGQUIT, catch);
  1180. X    (void) signal(SIGHUP, catch);
  1181. X    if (istool)
  1182. X        turnon(glob_flags, ECHO_FLAG);
  1183. X    tty_settings();
  1184. X#ifdef SIGCONT
  1185. X    (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  1186. X#endif /* SIGCONT */
  1187. X    /* echo_off() checks to see if echo_flg is set, so don't worry */
  1188. X    echo_off();
  1189. X    }
  1190. X
  1191. X    if (!istool && *argv) { /* we could check IS_SENDING */
  1192. X    char recipients[BUFSIZ];
  1193. X    (void) argv_to_string(recipients, argv);
  1194. X    fix_up_addr(recipients);
  1195. X    if (Flags.Cc && *(Flags.Cc))
  1196. X        fix_up_addr(Flags.Cc);
  1197. X    if (Flags.Bcc && *(Flags.Bcc))
  1198. X        fix_up_addr(Flags.Bcc);
  1199. X    /* prompt for subject and Cc list, but not "To: "
  1200. X     * mail_someone() already takes care of redirection.
  1201. X     * if -s or -c options are given, they will be passed.
  1202. X     */
  1203. X    if (do_set(set_options, "ask"))
  1204. X        turnon(Flags.flg, NEW_SUBJECT);
  1205. X    if (do_set(set_options, "autosign"))
  1206. X        turnon(Flags.flg, SIGN);
  1207. X    if (do_set(set_options, "autoedit"))
  1208. X        turnon(Flags.flg, EDIT);
  1209. X    if (do_set(set_options, "verbose"))
  1210. X        turnon(Flags.flg, VERBOSE);
  1211. X    if (do_set(set_options, "fortune"))
  1212. X        turnon(Flags.flg, DO_FORTUNE);
  1213. X    /* set now in case user is not running shell, but is running debug */
  1214. X    (void) signal(SIGCHLD, sigchldcatcher);
  1215. X    if (!setjmp(jmpbuf))
  1216. X        (void) mail_someone(recipients,
  1217. X                Flags.Subj,
  1218. X                Flags.Cc,
  1219. X                Flags.Bcc,
  1220. X                Flags.flg,
  1221. X                NULL);
  1222. X    /* do shell set from above: "mush -S user" perhaps */
  1223. X    if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
  1224. X        if (isoff(glob_flags, REDIRECT))
  1225. X        echo_on();
  1226. X        exit(0);
  1227. X    }
  1228. X    }
  1229. X    turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  1230. X
  1231. X    if (ison(glob_flags, REDIRECT)) {
  1232. X    puts("You can't redirect input unless you're sending mail.");
  1233. X    puts("If you want to run a shell with redirection, use \"-i\"");
  1234. X    cleanup(0);
  1235. X    }
  1236. X    if (!*mailfile) {
  1237. X    strdup(mailfile, spoolfile);
  1238. X    if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  1239. X        /* we know it's not the spool file here */
  1240. X        printf("No mail in %s.\n", mailfile);
  1241. X        echo_on(), exit(0);
  1242. X    }
  1243. X    }
  1244. X
  1245. X    if (!hdrs_only) {
  1246. X    /* catch will test DO_SHELL and try to longjmp if set.  this is a
  1247. X     * transition state from no-shell to do-shell to ignore sigs to
  1248. X     * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  1249. X     */
  1250. X    turnon(glob_flags, IGN_SIGS);
  1251. X#ifdef CURSES
  1252. X    if (ison(glob_flags, PRE_CURSES))
  1253. X        (void) curses_init(0, DUBL_NULL);
  1254. X    turnoff(glob_flags, PRE_CURSES);
  1255. X#endif /* CURSES */
  1256. X    }
  1257. X
  1258. X    /* find a free tmpfile */
  1259. X    if (!(p = do_set(set_options, "tmpdir")) &&
  1260. X    !(p = do_set(set_options, "home")))
  1261. Xalted:
  1262. X    p = ALTERNATE_HOME;
  1263. X    {
  1264. X    int pid = getpid();
  1265. X    while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, pid++), F_OK))
  1266. X    ;
  1267. X    }
  1268. X    /* just create the file, make sure it's empty.  It'll close later and
  1269. X     * be reopened for reading only.
  1270. X     */
  1271. X    if (!(tmpf = mask_fopen(tempfile, "w"))) {
  1272. X    if (strcmp(p, ALTERNATE_HOME))
  1273. X        goto alted;
  1274. X    error("Can't create tempfile %s", tempfile);
  1275. X    cleanup(0);
  1276. X    }
  1277. X
  1278. X    /* do pseudo-intelligent stuff with certain signals */
  1279. X    (void) signal(SIGINT,  catch);
  1280. X    (void) signal(SIGQUIT, catch);
  1281. X    (void) signal(SIGHUP,  catch);
  1282. X
  1283. X    if (!hdrs_only && !istool && (!Flags.src_file || !Flags.src_n_exit) &&
  1284. X    !do_set(set_options, "quiet"))
  1285. X    printf("%s: Type '?' for help.\n", VERSION);
  1286. X
  1287. X    (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile);
  1288. X    if (argv = make_command(buf, TRPL_NULL, &argc)) {
  1289. X    if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL))
  1290. X        turnoff(glob_flags, IGN_SIGS), cleanup(0);
  1291. X#ifdef CURSES
  1292. X    if (iscurses)
  1293. X        (void) curses_help_msg(TRUE);
  1294. X#endif /* CURSES */
  1295. X    free_vec(argv);
  1296. X    }
  1297. X
  1298. X    if (hdrs_only) {
  1299. X    (void) sprintf(buf, "headers %s", hdrs_only);
  1300. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  1301. X        (void) do_hdrs(argc, argv, NULL);
  1302. X    cleanup(0);
  1303. X    }
  1304. X
  1305. X    turnon(glob_flags, DO_SHELL);
  1306. X    if (istool && msg_cnt)
  1307. X    set_isread(current_msg);
  1308. X
  1309. X    /* finally, if the user wanted to source a file to execute, do it now */
  1310. X    if (Flags.src_file) {
  1311. X    char *s_argv[2];
  1312. X    s_argv[1] = Flags.src_file;
  1313. X    (void) source(2, s_argv);
  1314. X    if (!istool && Flags.src_n_exit)
  1315. X        cleanup(0);
  1316. X    }
  1317. X
  1318. X#ifdef SUNTOOL
  1319. X    if (istool) {
  1320. X    n = 0;
  1321. X    if (!tool_help) {
  1322. X        p = getpath(TOOL_HELP, &n);
  1323. X        if (n) {
  1324. X        fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p);
  1325. X        tool_help = "tool_help";
  1326. X        } else
  1327. X        strdup(tool_help, p);
  1328. X    }
  1329. X    if (time_out < 30)
  1330. X        time_out = 60;
  1331. X    turnoff(glob_flags, IGN_SIGS);
  1332. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  1333. X    timerclear(&(mail_timer.it_interval));
  1334. X    timerclear(&(mail_timer.it_value));
  1335. X    mail_timer.it_value.tv_sec = time_out;
  1336. X    setitimer(ITIMER_REAL, &mail_timer, NULL);
  1337. X    (void) signal(SIGALRM, check_new_mail);
  1338. X    unlock_cursors();
  1339. X    while (!(tool->tl_flags & TOOL_DONE))
  1340. X        tool_select(tool, 1);
  1341. X    cleanup(0);
  1342. X    }
  1343. X#endif /* SUNTOOL */
  1344. X    do_loop();
  1345. X}
  1346. X
  1347. Xdo_version()
  1348. X{
  1349. X#ifdef PATCHDATE
  1350. X    print("%s [%s]\n", VERSION, PATCHDATE);
  1351. X#else /* !PATCHDATE */
  1352. X    print("%s\n", VERSION);
  1353. X#endif /* PATCHDATE */
  1354. X    return -1;
  1355. X}
  1356. X
  1357. X/* set the current working directory */
  1358. Xset_cwd()
  1359. X{
  1360. X    char buf[MAXPATHLEN], cwd[MAXPATHLEN];
  1361. X#ifndef SYSV
  1362. X    extern char *getwd();
  1363. X#else /* SYSV */
  1364. X    extern char *getcwd();
  1365. X#endif /* SYSV */
  1366. X
  1367. X#ifndef SYSV
  1368. X    if (getwd(cwd) == NULL)
  1369. X#else
  1370. X    if (getcwd(cwd, MAXPATHLEN) == NULL)
  1371. X#endif /* SYSV */
  1372. X    {
  1373. X    error("getcwd: %s", cwd);
  1374. X    (void) un_set(&set_options, "cwd");
  1375. X    } else {
  1376. X    char *argv[4];
  1377. X    argv[0] = "cwd";
  1378. X    argv[1] = "=";
  1379. X    argv[2] = cwd;
  1380. X    argv[3] = NULL;
  1381. X    (void) add_option(&set_options, argv);
  1382. X    }
  1383. X}
  1384. END_OF_FILE
  1385. if test 8512 -ne `wc -c <'main.c'`; then
  1386.     echo shar: \"'main.c'\" unpacked with wrong size!
  1387. fi
  1388. # end of 'main.c'
  1389. fi
  1390. if test -f 'main_panel.c' -a "${1}" != "-c" ; then 
  1391.   echo shar: Will not clobber existing file \"'main_panel.c'\"
  1392. else
  1393. echo shar: Extracting \"'main_panel.c'\" \(9189 characters\)
  1394. sed "s/^X//" >'main_panel.c' <<'END_OF_FILE'
  1395. X/* "@(#)main_panel.c    (c) copyright    10/18/86 (Dan Heller) */
  1396. X
  1397. X#include "mush.h"
  1398. X
  1399. Xmake_main_panel(choice_args, button_args)
  1400. Xchar **choice_args, **button_args;
  1401. X{
  1402. X    /* main panel stuff: */
  1403. X    panel_sw = panel_create(tool,
  1404. X    PANEL_HEIGHT, 80,
  1405. X    0);
  1406. X    main_panel = (Panel)panel_sw->ts_data;
  1407. X
  1408. X    quit_item = panel_create_item(main_panel, PANEL_CHOICE,
  1409. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1410. X    PANEL_ITEM_X,            4,
  1411. X    PANEL_ITEM_Y,            4,
  1412. X    PANEL_LABEL_IMAGE,
  1413. X        panel_button_image(main_panel, "Done", 6, fonts[LARGE]),
  1414. X    PANEL_MENU_TITLE_STRING,     "Done",
  1415. X    PANEL_CHOICE_STRINGS,         "Close to Icon",
  1416. X                    "Quit Tool",
  1417. X                    "Help",
  1418. X                    0,
  1419. X    PANEL_NOTIFY_PROC,         toolquit,
  1420. X    0);
  1421. X
  1422. X    help_item = panel_create_item(main_panel, PANEL_CHOICE,
  1423. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1424. X    PANEL_ITEM_X,            79,
  1425. X    PANEL_ITEM_Y,            4,
  1426. X    PANEL_LABEL_IMAGE,
  1427. X        panel_button_image(main_panel, "Help", 4, fonts[LARGE]),
  1428. X    PANEL_MENU_TITLE_STRING,     "Available Help",
  1429. X    PANEL_CHOICE_STRINGS,         "General",
  1430. X                    "Help with \"help\"",
  1431. X                    "The Mouse",
  1432. X                    "Windows",
  1433. X                    "Function Keys",
  1434. X                    "Message headers",
  1435. X                    "Message lists",
  1436. X                    0,
  1437. X    PANEL_NOTIFY_PROC,         do_help,
  1438. X    0);
  1439. X
  1440. X    read_item = panel_create_item(main_panel, PANEL_CHOICE,
  1441. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1442. X    PANEL_ITEM_X,            136,
  1443. X    PANEL_ITEM_Y,            4,
  1444. X    PANEL_LABEL_IMAGE,
  1445. X        panel_button_image(main_panel, "Next", 4, fonts[LARGE]),
  1446. X    PANEL_MENU_TITLE_STRING,     "Next Message",
  1447. X    PANEL_CHOICE_STRINGS,         "Read Next", "Help", 0,
  1448. X    PANEL_NOTIFY_PROC,         read_mail,
  1449. X    0);
  1450. X
  1451. X    respond_item = panel_create_item(main_panel, PANEL_CHOICE,
  1452. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1453. X    PANEL_ITEM_X,            193,
  1454. X    PANEL_ITEM_Y,            4,
  1455. X    PANEL_LABEL_IMAGE,
  1456. X        panel_button_image(main_panel, "Reply", 5, fonts[LARGE]),
  1457. X    PANEL_MENU_TITLE_STRING,     "Respond to Current Message",
  1458. X    PANEL_CHOICE_STRINGS,         "Sender Only",
  1459. X                    "Sender Only (include msg)",
  1460. X                    "All Recipients",
  1461. X                    "All Recipients (include msg)",
  1462. X                    "Help", 0,
  1463. X    PANEL_NOTIFY_PROC,         respond_mail,
  1464. X    0);
  1465. X
  1466. X    delete_item = panel_create_item(main_panel, PANEL_CHOICE,
  1467. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1468. X    PANEL_ITEM_X,            259,
  1469. X    PANEL_ITEM_Y,            4,
  1470. X    PANEL_LABEL_IMAGE,
  1471. X        panel_button_image(main_panel, "Delete", 6, fonts[LARGE]),
  1472. X    PANEL_MENU_TITLE_STRING,     "Delete/Undelete Messages",
  1473. X    PANEL_CHOICE_STRINGS,         "Delete",
  1474. X                    "Undelete",
  1475. X                    "Help", 0,
  1476. X    PANEL_NOTIFY_PROC,         delete_mail,
  1477. X    0);
  1478. X
  1479. X    sort_item = panel_create_item(main_panel, PANEL_CHOICE,
  1480. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1481. X    PANEL_ITEM_X,            334,
  1482. X    PANEL_ITEM_Y,            4,
  1483. X    PANEL_LABEL_IMAGE,
  1484. X        panel_button_image(main_panel, "Sort", 4, fonts[LARGE]),
  1485. X    PANEL_MENU_TITLE_STRING,     "Sort Messages",
  1486. X    PANEL_CHOICE_STRINGS,         "By Date",
  1487. X                    "By Author",
  1488. X                    "By Subject",
  1489. X                    "By Subject (ignore Re:)",
  1490. X                    "By Status",
  1491. X                    "Help", 0,
  1492. X    PANEL_NOTIFY_PROC,         do_sort,
  1493. X    0);
  1494. X
  1495. X    option_item = panel_create_item(main_panel, PANEL_CHOICE,
  1496. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1497. X    PANEL_ITEM_X,            391,
  1498. X    PANEL_ITEM_Y,            4,
  1499. X    PANEL_LABEL_IMAGE,
  1500. X        panel_button_image(main_panel, "Opts", 4, fonts[LARGE]),
  1501. X    PANEL_MENU_TITLE_STRING,     "Mail Options",
  1502. X    PANEL_CHOICE_STRINGS,         "Set Options", "Function keys",
  1503. X                    "Help", 0,
  1504. X    PANEL_NOTIFY_PROC,         p_set_opts,
  1505. X    0);
  1506. X
  1507. X    alias_item = panel_create_item(main_panel, PANEL_CHOICE,
  1508. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1509. X    PANEL_ITEM_X,            448,
  1510. X    PANEL_ITEM_Y,            4,
  1511. X    PANEL_LABEL_IMAGE,
  1512. X        panel_button_image(main_panel, "Aliases", 7, fonts[LARGE]),
  1513. X    PANEL_MENU_TITLE_STRING,     "Mail Aliases",
  1514. X    PANEL_CHOICE_STRINGS,         "Current Aliases",
  1515. X                    "Add/Change alias",
  1516. X                    "Unalias", "Help", 0,
  1517. X    PANEL_NOTIFY_PROC,         p_set_opts,
  1518. X    0);
  1519. X
  1520. X    comp_item = panel_create_item(main_panel, PANEL_CHOICE,
  1521. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1522. X    PANEL_ITEM_X,            532,
  1523. X    PANEL_ITEM_Y,            4,
  1524. X    PANEL_LABEL_IMAGE,
  1525. X        panel_button_image(main_panel, "Compose", 8, fonts[LARGE]),
  1526. X    PANEL_MENU_TITLE_STRING,     "Compose a letter",
  1527. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  1528. X    PANEL_NOTIFY_PROC,         do_compose,
  1529. X    0);
  1530. X
  1531. X    file_item = panel_create_item(main_panel, PANEL_TEXT,
  1532. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1533. X    PANEL_ITEM_X,            4,
  1534. X    PANEL_ITEM_Y,            30,
  1535. X    PANEL_LABEL_FONT,         fonts[DEFAULT],
  1536. X    PANEL_SHOW_MENU,        TRUE,
  1537. X    PANEL_LABEL_STRING,         "filename:",
  1538. X    PANEL_MENU_CHOICE_STRINGS,    "Save message without message header",0,
  1539. X    PANEL_VALUE_DISPLAY_LENGTH,     35,
  1540. X    PANEL_NOTIFY_STRING,         "\n\r",
  1541. X    PANEL_NOTIFY_PROC,         file_dir,
  1542. X    0);
  1543. X
  1544. X    input_item = panel_create_item(main_panel, PANEL_TEXT,
  1545. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1546. X    PANEL_ITEM_X,            373,
  1547. X    PANEL_ITEM_Y,            30,
  1548. X    PANEL_SHOW_ITEM,         FALSE,
  1549. X    PANEL_SHOW_MENU,         TRUE,
  1550. X    PANEL_LABEL_FONT,         fonts[DEFAULT],
  1551. X    PANEL_VALUE_DISPLAY_LENGTH,     20,
  1552. X    PANEL_NOTIFY_STRING,         "\n\r",
  1553. X    PANEL_NOTIFY_PROC,         text_done,
  1554. X    0);
  1555. X
  1556. X    print_item = panel_create_item(main_panel, PANEL_CHOICE,
  1557. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1558. X    PANEL_ITEM_X,            4,
  1559. X    PANEL_ITEM_Y,            50,
  1560. X    PANEL_LABEL_IMAGE,
  1561. X        panel_button_image(main_panel, "Printer", 7, fonts[LARGE]),
  1562. X    PANEL_MENU_TITLE_STRING,     "Printing Messages",
  1563. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  1564. X    PANEL_NOTIFY_PROC,         do_lpr,
  1565. X    0);
  1566. X
  1567. X    folder_item = panel_create_item(main_panel, PANEL_CHOICE,
  1568. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1569. X    PANEL_ITEM_X,            88,
  1570. X    PANEL_ITEM_Y,            50,
  1571. X    PANEL_LABEL_IMAGE,
  1572. X        panel_button_image(main_panel, "folder", 6, fonts[LARGE]),
  1573. X    PANEL_MENU_TITLE_STRING,     "Change folder",
  1574. X    PANEL_CHOICE_STRINGS,         "System Mailbox",
  1575. X                    "Main Mailbox",
  1576. X                    "Last Accessed Folder",
  1577. X                    0,
  1578. X    PANEL_NOTIFY_PROC,         do_file_dir,
  1579. X    0);
  1580. X
  1581. X    add_folder_to_menu(folder_item, 3);
  1582. X
  1583. X    save_item = panel_create_item(main_panel, PANEL_CHOICE,
  1584. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1585. X    PANEL_ITEM_X,            163,
  1586. X    PANEL_ITEM_Y,            50,
  1587. X    PANEL_LABEL_IMAGE,
  1588. X        panel_button_image(main_panel, "Save", 4, fonts[LARGE]),
  1589. X    PANEL_MENU_TITLE_STRING,     "Save messages",
  1590. X    PANEL_CHOICE_STRINGS,         "~/mbox", 0,
  1591. X    PANEL_NOTIFY_PROC,         do_file_dir,
  1592. X    0);
  1593. X
  1594. X    add_folder_to_menu(save_item, 1);
  1595. X
  1596. X    cd_item = panel_create_item(main_panel, PANEL_CHOICE,
  1597. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1598. X    PANEL_ITEM_X,            220,
  1599. X    PANEL_ITEM_Y,            50,
  1600. X    PANEL_LABEL_IMAGE,
  1601. X        panel_button_image(main_panel, "chdir", 5, fonts[LARGE]),
  1602. X    PANEL_MENU_TITLE_STRING,     "Change Working Directory",
  1603. X    PANEL_CHOICE_STRINGS,         "Print Current directory",
  1604. X                    "HOME directory",
  1605. X                    "Private Mail directory.",
  1606. X                    "Help", 0,
  1607. X    PANEL_NOTIFY_PROC,         do_file_dir,
  1608. X    0);
  1609. X
  1610. X    update_item = panel_create_item(main_panel, PANEL_CHOICE,
  1611. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1612. X    PANEL_ITEM_X,            286,
  1613. X    PANEL_ITEM_Y,            50,
  1614. X    PANEL_LABEL_IMAGE,
  1615. X        panel_button_image(main_panel, "Update", 6, fonts[LARGE]),
  1616. X    PANEL_MENU_TITLE_STRING,     "Updating folders",
  1617. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  1618. X    PANEL_NOTIFY_PROC,         do_update,
  1619. X    0);
  1620. X
  1621. X    send_item = panel_create_item(main_panel, PANEL_CHOICE,
  1622. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1623. X    PANEL_ITEM_X,            361,
  1624. X    PANEL_ITEM_Y,            50,
  1625. X    PANEL_SHOW_ITEM,         FALSE,
  1626. X    PANEL_LABEL_IMAGE,
  1627. X        panel_button_image(main_panel, "Send", 6, fonts[LARGE]),
  1628. X    PANEL_MENU_TITLE_STRING,     "Send Letter",
  1629. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  1630. X    PANEL_NOTIFY_PROC,         do_send,
  1631. X    0);
  1632. X
  1633. X    edit_item = panel_create_item(main_panel, PANEL_CHOICE,
  1634. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1635. X    PANEL_ITEM_X,            436,
  1636. X    PANEL_ITEM_Y,            50,
  1637. X    PANEL_SHOW_ITEM,         FALSE,
  1638. X    PANEL_LABEL_IMAGE,
  1639. X        panel_button_image(main_panel, "Editor", 4, fonts[LARGE]),
  1640. X    PANEL_MENU_TITLE_STRING,     "Editing",
  1641. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  1642. X    PANEL_NOTIFY_PROC,         do_edit,
  1643. X    0);
  1644. X
  1645. X    abort_item = panel_create_item(main_panel, PANEL_BUTTON,
  1646. X    PANEL_ATTRIBUTE_LIST,         button_args,
  1647. X    PANEL_ITEM_X,            511,
  1648. X    PANEL_ITEM_Y,            50,
  1649. X    PANEL_SHOW_ITEM,         FALSE,
  1650. X    PANEL_LABEL_IMAGE,
  1651. X        panel_button_image(main_panel, "Abort", 5, fonts[LARGE]),
  1652. X    PANEL_NOTIFY_PROC,         abort_mail,
  1653. X    0);
  1654. X
  1655. X    font_item = panel_create_item(main_panel, PANEL_CHOICE,
  1656. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  1657. X    PANEL_ITEM_X,            577,
  1658. X    PANEL_ITEM_Y,            50,
  1659. X    PANEL_LABEL_IMAGE,
  1660. X        panel_button_image(main_panel, "Fonts", 5, fonts[LARGE]),
  1661. X    PANEL_MENU_TITLE_STRING,     "Fonts",
  1662. X    PANEL_SHOW_MENU_MARK,         TRUE,
  1663. X    PANEL_CHOICE_FONTS,         fonts[0], fonts[1], fonts[2], 0,
  1664. X    PANEL_CHOICE_STRINGS,         "Default", "Small", "Large", 0,
  1665. X    PANEL_NOTIFY_PROC,         change_font,
  1666. X    0);
  1667. X}
  1668. X
  1669. X/*
  1670. X * Open the user's mail folder (either user set or default path) and find all
  1671. X * the files (assumed to be mail folders) and add them to the menu list of
  1672. X * folders to use.
  1673. X */
  1674. Xadd_folder_to_menu(item, n)
  1675. Xstruct panel_item *item;
  1676. Xregister int       n;
  1677. X{
  1678. X    register FILE     *pp = NULL_FILE;
  1679. X    register char    *p, *tmp = NULL;
  1680. X    int            x = 0;
  1681. X    char         buf[128], path[128];
  1682. X
  1683. X    if (!(p = do_set(set_options, "folder")) || !*p)
  1684. X    p = DEF_FOLDER;
  1685. X    if (p) {
  1686. X    tmp = getpath(p, &x);
  1687. X    if (x == -1) {
  1688. X        if (errno != ENOENT)
  1689. X        print("%s: %s\n", p, tmp);
  1690. X        tmp = NULL;
  1691. X    }
  1692. X    }
  1693. X    if (p = tmp) {
  1694. X    p = sprintf(buf, "%s %s", LS_COMMAND, p);
  1695. X    if (!(pp = popen(buf, "r")))
  1696. X        error(buf);
  1697. X    else {
  1698. X        *path = '+';
  1699. X        while (fgets(path+1, 128, pp)) {
  1700. X        struct stat s_buf;
  1701. X        if (p = index(path+1, '\n'))
  1702. X            *p = 0;
  1703. X        (void) sprintf(buf, "%s/%s", tmp, path+1);
  1704. X        if (stat(buf, &s_buf) || s_buf.st_mode & S_IFDIR)
  1705. X            continue;
  1706. X        panel_set(item, PANEL_CHOICE_STRING, n++, path, 0);
  1707. X        }
  1708. X        pclose(pp);
  1709. X    }
  1710. X    }
  1711. X    panel_set(item, PANEL_CHOICE_STRING, n, "Help", 0);
  1712. X}
  1713. END_OF_FILE
  1714. if test 9189 -ne `wc -c <'main_panel.c'`; then
  1715.     echo shar: \"'main_panel.c'\" unpacked with wrong size!
  1716. fi
  1717. # end of 'main_panel.c'
  1718. fi
  1719. if test -f 'options.c' -a "${1}" != "-c" ; then 
  1720.   echo shar: Will not clobber existing file \"'options.c'\"
  1721. else
  1722. echo shar: Extracting \"'options.c'\" \(7815 characters\)
  1723. sed "s/^X//" >'options.c' <<'END_OF_FILE'
  1724. X/* @(#)options.c    (c) copyright 10/10/88 (Dan Heller, Bart Schaefer) */
  1725. X
  1726. X#include "mush.h"
  1727. X#include "options.h"
  1728. X
  1729. X/*
  1730. X * NOTE:  Any word flag which is a prefix of another word flag must be
  1731. X *  listed AFTER the flag it prefixes in the list below
  1732. X */
  1733. X
  1734. Xchar *word_flags[][2] = {
  1735. X    { "-bcc",        "-b" },
  1736. X    { "-blindcarbon",    "-b" },
  1737. X    { "-blind",        "-b" },
  1738. X    { "-carbon",    "-c" },
  1739. X    { "-cc",        "-c" },
  1740. X    { "-copy",        "-c" },
  1741. X    { "-curses",    "-C" },
  1742. X    { "-debug",        "-d" },
  1743. X    { "-echo",        "-e" },
  1744. X    { "-folder",    "-f" },    /* Maybe -file should become -f too? */
  1745. X    { "-file",        "-F" },    /* Don't really like -file for -F */
  1746. X    { "-headers",    "-H" },
  1747. X    { "-help",        "-1" },
  1748. X    { "-interact",    "-i" },
  1749. X    { "-mailbox",    "-m" },
  1750. X    { "-noheaders",    "-N" },
  1751. X    { "-noinit",    "-n" },
  1752. X    { "-readonly",    "-r" },
  1753. X    { "-shell",        "-S" },
  1754. X    { "-source",    "-F" },    /* This is better for -F */
  1755. X    { "-subject",    "-s" },
  1756. X    { "-sunhelp",    "-2" },
  1757. X    { "-timeout",    "-T" },
  1758. X    { "-tool",        "-t" },
  1759. X    { "-user",        "-u" },
  1760. X    { "-verbose",    "-v" },
  1761. X    { "-visual",    "-C" },
  1762. X    { NULL,        NULL }    /* This must be the last entry */
  1763. X};
  1764. X
  1765. Xfix_word_flags(argv)
  1766. Xregister char **argv;
  1767. X{
  1768. X    int i;
  1769. X    Debug(*argv);
  1770. X    for (++argv; *argv; argv++) {
  1771. X    for (i = 0; word_flags[i][0]; i++) {
  1772. X        int len = strlen(word_flags[i][0]);
  1773. X        if (! strncmp(*argv, word_flags[i][0], len)) {
  1774. X        char buf[BUFSIZ], *p = buf;
  1775. X        p += Strcpy(buf, word_flags[i][1]);
  1776. X        (void) strcpy(p, *argv + len);
  1777. X        (void) strcpy(*argv, buf);
  1778. X        }
  1779. X    }
  1780. X    Debug(" %s", *argv);
  1781. X    }
  1782. X    if (debug)
  1783. X    putchar('\n');
  1784. X}
  1785. X
  1786. X/*
  1787. X * preparse the command line to determine whether or not we're going
  1788. X * to bail out after checking that the user has no mail.  Also, check
  1789. X * to see if we're going to run a tool because it must be built first.
  1790. X */
  1791. Xpreparse_opts(argcp, argv, argt)
  1792. Xregister int *argcp;    /* Pointer to argument count */
  1793. Xregister char **argv;    /* Argument vector */
  1794. Xregister char ***argt;    /* Pointer to tool-mode arg vector */
  1795. X{
  1796. X    int n = FALSE;
  1797. X    char **args;
  1798. X
  1799. X#ifdef SUNTOOL
  1800. X    if (n = istool = strlen(prog_name) > 3 &&
  1801. X         !strcmp(prog_name+strlen(prog_name)-4, "tool"))
  1802. X    turnon(glob_flags, DO_SHELL);
  1803. X#endif /* SUNTOOL */
  1804. X
  1805. X    fix_word_flags(argv);
  1806. X
  1807. X    if (!istool && *argcp > 1) {
  1808. X    for (args = argv+1; *args && args[0][0] == '-'; args++) {
  1809. X        int next = 1;
  1810. XDoNext:
  1811. X        switch (args[0][next]) {
  1812. X#ifdef SUNTOOL
  1813. X        case 'T' :
  1814. X            if (args[1])
  1815. X            args++;
  1816. X        case 't' :
  1817. X            istool = 1;
  1818. X            n = TRUE;
  1819. X            turnon(glob_flags, DO_SHELL);
  1820. X            break;
  1821. X#endif /* SUNTOOL */
  1822. X        case 'S' :
  1823. X            turnon(glob_flags, DO_SHELL);
  1824. X            n = TRUE;
  1825. X            break;
  1826. X        case 'f' :
  1827. X        case 'F' :
  1828. X        case 'm' :
  1829. X        case 'u' :
  1830. X            n = TRUE;
  1831. X        case 'b' :
  1832. X        case 'c' :
  1833. X        case 's' :
  1834. X        case '1' :
  1835. X        case '2' :
  1836. X            if (args[1]) {
  1837. X            args++;
  1838. X            next = 0;
  1839. X            }
  1840. X            break;
  1841. X        case '\0':
  1842. X            next = 0;
  1843. X        default : ;
  1844. X        }
  1845. X        if (next) {
  1846. X        ++next;
  1847. X        goto DoNext;
  1848. X        }
  1849. X    }
  1850. X    if (*args) {  /* unused args indicates sending mail to someone */
  1851. X        n = TRUE;
  1852. X        if (!istool)
  1853. X        turnon(glob_flags, IS_SENDING);
  1854. X    }
  1855. X    }
  1856. X
  1857. X#ifdef SUNTOOL
  1858. X    /* even if not running tool mode parse all potential suntools args out */
  1859. X    tool_parse_all(argcp, argv, argt, prog_name);
  1860. X#endif /* SUNTOOL */
  1861. X
  1862. X    return n;
  1863. X}
  1864. X
  1865. Xstatic char *usage_str =
  1866. X#ifdef SUNTOOL 
  1867. X    "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-t] [-s subject] [users]\n";
  1868. X#else
  1869. X#ifdef CURSES
  1870. X    "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  1871. X#else
  1872. X    "usage: %s [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  1873. X#endif /* CURSES */
  1874. X#endif /* SUNTOOL */
  1875. X
  1876. Xparse_options(argvp, flags)
  1877. Xregister char ***argvp;
  1878. Xstruct mush_flags *flags;
  1879. X{
  1880. X    char buf[256];
  1881. X
  1882. X    bzero(flags, sizeof (struct mush_flags));
  1883. X    flags->source_rc = TRUE;
  1884. X    mailfile = "";
  1885. X
  1886. X    for (++(*argvp); **argvp && ***argvp == '-'; (*argvp)++) {
  1887. X    int look_again;
  1888. XDoLookAgain:
  1889. X    look_again = TRUE;
  1890. X    switch ((*argvp)[0][1]) {
  1891. X        case 'e':
  1892. X        /*
  1893. X         * don't set tty modes -- e.g. echo and cbreak modes aren't
  1894. X         * changed.
  1895. X         */
  1896. X        turnon(glob_flags, ECHO_FLAG);
  1897. X#ifdef CURSES
  1898. X        when 'C':
  1899. X        /* don't init curses -- don't even set iscurses.   */
  1900. X        if (istool) {
  1901. X            puts("-C: You are already running in tool mode");
  1902. X            turnoff(glob_flags, PRE_CURSES);
  1903. X        } else if (hdrs_only)
  1904. X            puts("headers only: ignoring -C flag");
  1905. X        else
  1906. X            turnon(glob_flags, PRE_CURSES);
  1907. X#endif /* CURSES */
  1908. X        when 'F':
  1909. X        flags->src_n_exit = ((*argvp)[0][2] == '!');
  1910. X        if (!(flags->src_file = *++(*argvp)))
  1911. X            puts("specify filename to source"), exit(1);
  1912. X        look_again = FALSE;
  1913. X        /* fall thru! */
  1914. X        case 'N':
  1915. X        (void) strcat(flags->f_flags, "-N ");
  1916. X        when 'r':
  1917. X        (void) strcat(flags->f_flags, "-r "); /* folder() argument */
  1918. X        when 'H':
  1919. X        if (istool) {
  1920. X            puts("running in tool-mode; -H option ignored.");
  1921. X            break;
  1922. X        }
  1923. X        turnoff(glob_flags, PRE_CURSES);
  1924. X        if (*(hdrs_only = (*(*argvp))+2) != ':')
  1925. X            hdrs_only = ":a";
  1926. X        else
  1927. X            look_again = FALSE;
  1928. X        /* read only cuz no updates */
  1929. X        (void) strcat(flags->f_flags, "-N -r ");
  1930. X        when 'i':
  1931. X        /* force interactive even if !isatty(0) */
  1932. X        turnoff(glob_flags, REDIRECT);
  1933. X        when 'u': /* specify a user's mailbox */
  1934. X        if (*mailfile)
  1935. X            puts("You can't specify more than one mailbox"), exit(1);
  1936. X#ifdef HOMEMAIL
  1937. X        {
  1938. X            char *p;
  1939. X            int isdir = 1;
  1940. X            (void) sprintf(buf, "%%%s",
  1941. X                (*argvp)[1] ? (*argvp)[1] : "root");
  1942. X            if ((p = getpath(buf, &isdir)) && !isdir)
  1943. X            strdup(mailfile, p);
  1944. X            else if (isdir < 0)
  1945. X            puts(p), exit(1);
  1946. X            else if (isdir)
  1947. X            printf("\"%s\" is a directory\n", p), exit(1);
  1948. X        }
  1949. X#else /* HOMEMAIL */
  1950. X        strdup(mailfile, sprintf(buf, "%s/%s",
  1951. X                   MAILDIR, ((*argvp)[1])? (*argvp)[1] : "root"));
  1952. X#endif /* HOMEMAIL */
  1953. X        if ((*argvp)[1])
  1954. X            ++(*argvp);
  1955. X        look_again = FALSE;
  1956. X        when 'm':
  1957. X        if ((*argvp)[1])
  1958. X            strdup(spoolfile, *++(*argvp));
  1959. X        else
  1960. X            printf("-m: missing mailbox name.\n"), exit(1);
  1961. X        look_again = FALSE;
  1962. X        when 'f':
  1963. X        if (*mailfile)
  1964. X            puts("You can't specify more than one mailbox"), exit(1);
  1965. X        if ((*argvp)[1]) {
  1966. X            strdup(mailfile, *++(*argvp));
  1967. X            look_again = FALSE;
  1968. X        } else
  1969. X            strdup(mailfile, "&");
  1970. X        when '1':
  1971. X        if ((*argvp)[1])
  1972. X            strdup(cmd_help, *++(*argvp));
  1973. X        else
  1974. X            puts("-1 \"filename\""), exit(1);
  1975. X        look_again = FALSE;
  1976. X#ifdef SUNTOOL
  1977. X        when '2':
  1978. X        if ((*argvp)[1])
  1979. X            strdup(tool_help, *++(*argvp));
  1980. X        else
  1981. X            puts("-2 \"filename\""), exit(1);
  1982. X        look_again = FALSE;
  1983. X#endif /* SUNTOOL */
  1984. X        when 's':
  1985. X        if (istool)
  1986. X            puts("bad option when run as a tool"), exit(1);
  1987. X        else if ((*argvp)[1])
  1988. X            flags->Subj = *++(*argvp);
  1989. X        else
  1990. X            puts("-s \"subject\""), exit(1);
  1991. X        look_again = FALSE;
  1992. X        when 'b':
  1993. X        if (istool)
  1994. X            puts("-b: bad option when run as a tool"), exit(1);
  1995. X        else if ((*argvp)[1])
  1996. X            flags->Bcc = *++(*argvp);
  1997. X        else
  1998. X            puts("-b \"bcc list\""), exit(1);
  1999. X        look_again = FALSE;
  2000. X        when 'c':
  2001. X        if (istool)
  2002. X            puts("-c: bad option when run as a tool"), exit(1);
  2003. X        else if ((*argvp)[1])
  2004. X            flags->Cc = *++(*argvp);
  2005. X        else
  2006. X            puts("-c \"cc list\""), exit(1);
  2007. X        look_again = FALSE;
  2008. X        break;
  2009. X#ifdef VERBOSE_ARG
  2010. X        case 'v':
  2011. X        if (istool)
  2012. X            puts("bad option when run as a tool"), exit(1);
  2013. X        turnon(flags->flg, VERBOSE);
  2014. X        break;
  2015. X#endif /* VERBOSE_ARG */
  2016. X#ifdef SUNTOOL
  2017. X            case 'T':
  2018. X        if ((time_out = atoi(*(*argvp))) <= 29)
  2019. X            time_out = 30;
  2020. X        look_again = FALSE;
  2021. X        /* -T implies -t */
  2022. X        case 't': istool = 1;
  2023. X#endif /* SUNTOOL */
  2024. X        case 'S': turnon(glob_flags, DO_SHELL);
  2025. X        when 'n': flags->source_rc = FALSE;
  2026. X        when 'd': debug = 1;
  2027. X        when '\0' : look_again = FALSE;
  2028. X        otherwise:
  2029. X        print("%s: unknown option: `%c'\n", prog_name,
  2030. X            (*argvp)[0][1]? (*argvp)[0][1] : '-');
  2031. X        print(usage_str, prog_name);
  2032. X    }
  2033. X    if (look_again && ++(**argvp) != '\0')
  2034. X        goto DoLookAgain;
  2035. X    }
  2036. X}
  2037. END_OF_FILE
  2038. if test 7815 -ne `wc -c <'options.c'`; then
  2039.     echo shar: \"'options.c'\" unpacked with wrong size!
  2040. fi
  2041. # end of 'options.c'
  2042. fi
  2043. echo shar: End of archive 4 \(of 19\).
  2044. cp /dev/null ark4isdone
  2045. MISSING=""
  2046. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  2047.     if test ! -f ark${I}isdone ; then
  2048.     MISSING="${MISSING} ${I}"
  2049.     fi
  2050. done
  2051. if test "${MISSING}" = "" ; then
  2052.     echo You have unpacked all 19 archives.
  2053.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2054. else
  2055.     echo You still need to unpack the following archives:
  2056.     echo "        " ${MISSING}
  2057. fi
  2058. ##  End of shell archive.
  2059. exit 0
  2060.